﻿<template>
  <div class = "widget-form-container">
    <el-form :size = "data.config.itemSize" :label-position = "data.config.labelPosition" :label-width = "data.config.labelWidth + 'px'" :inline = "data.config.inline">
      <draggable class = "widget-form-list" style = 'min-height:500px'
      v-model = "data.list" v-bind = "{group:{ name:'people'}, sort:true}" @add = "handleFormItemAdd">
        <template v-for = "(element, index) in data.list">
          <!-- 栅格布局时 -->
          <template v-if = "element.type == 'grid'">
            <div v-if = "element && element.key"  class = "widget-grid-container data-grid" :key = "element.key" style = "position: relative;">
              <el-row class = "widget-grid"
                type = "flex"
                :class = "{active: selectFormItem.key == element.key}"
                :gutter = "element.options.gutter ? element.options.gutter : 0"
                :justify = "element.options.justify"
                :align = "element.options.align"
                @click.native = "handleselectFormItem(index)">
                <el-col v-for = "(col, colIndex) in element.columns" :key = "colIndex" :span = "col.span ? col.span : 0"
                :class = "(Object.keys(col).indexOf('isButtonGroup') !== -1 && col.isButtonGroup) ? 'el_col_buttonGroup' : ''">
                  <div style = "border: 1px dashed #999;">
                    <draggable
                      class = "widget-form-list"
                      style = "padding-bottom: 50px;"
                      v-model = "col.list"
                      filter = "widget-grid-container"
                      v-bind = "{group:'people', sort:true}"
                      @add = "handleFormItemColAdd($event, element, colIndex)">
                      <template>
                        <form-item  v-for = "(el, i) in col.list" :key = "el.key" :element = "el" :select.sync = "selectFormItem" :index = "i" :data = "col"></form-item>
                      </template>
                    </draggable>
                  </div>
                </el-col>
              </el-row>
              <el-button title = "删除" style = "bottom: -20px;" @click.stop = "handleFormItemDelete(index)" class = "widget-action-delete" v-if = "selectFormItem.key == element.key" circle plain type = "danger">
                <i class = "iconfont icon-shanchu" ></i>
              </el-button>
            </div>
          </template>
          <!-- tabs标签页时--内容可能会有栅格布局 -->
          <template v-else-if = "element.type == 'tabs'">
            <div v-if = "element && element.key"  class = "tabs-grid" :key = "element.key" style = "position: relative;">
              <el-tabs :type = "element.options.tabType" :stretch = "element.options.stretch" @click.native = "handleselectFormItem(index)">
                <el-tab-pane v-for = "(tabItem, tabIndex) in element.tabList" :key = "tabIndex" :label = "tabItem.label">
                  <draggable class = "widget-form-list" style = "padding-bottom: 50px;" v-model = "tabItem.list" filter = "tabs-grid"
                  v-bind = "{group:'people', sort:true}"
                  @add = "handleFormItemTabAdd($event, element, tabIndex)">
                    <template v-for = "(el, i) in tabItem.list">
                      <template v-if = "el.type == 'grid'">
                        <div v-if = "el && el.key"  class = "widget-grid-container data-grid" :key = "el.key" style = "position: relative;">
                          <el-row class = "widget-grid"
                            type = "flex"
                            :class = "{active: selectFormItem.key == el.key}"
                            :gutter = "el.options.gutter ? el.options.gutter : 0"
                            :justify = "el.options.justify"
                            :align = "el.options.align"
                            @click.native.stop = "handleselectTabsFormItem(index, tabIndex, i)">
                            <el-col v-for = "(col, colIndex) in el.columns" :key = "colIndex" :span = "col.span ? col.span : 0"
                            :class = "(Object.keys(col).indexOf('isButtonGroup') !== -1 && col.isButtonGroup) ? 'el_col_buttonGroup' : ''">
                              <div style = "border: 1px dashed #999;">
                                <draggable
                                  class = "widget-form-list"
                                  style = "padding-bottom: 50px;"
                                  v-model = "col.list"
                                  filter = "widget-grid-container"
                                  v-bind = "{group:'people', sort:true}"
                                  @add = "handleFormItemColAdd($event, el, colIndex)">
                                  <template>
                                    <form-item  v-for = "(el, is) in col.list" :key = "el.key" :element = "el" :select.sync = "selectFormItem" :index = "is" :data = "col"></form-item>
                                  </template>
                                </draggable>
                              </div>
                            </el-col>
                          </el-row>
                          <el-button title = "删除" style = "bottom: -20px;" @click.stop = "handleFormTabsItemDelete(index, tabIndex, i)" class = "widget-action-delete" v-if = "selectFormItem.key == el.key" circle plain type = "danger">
                            <i class = "iconfont icon-shanchu" ></i>
                          </el-button>
                        </div>
                      </template>
                      <template v-else>
                        <form-item  v-if = "el && el.key"  :key = "el.key" :element = "el" :select.sync = "selectFormItem" :index = "i" :data = "tabItem"></form-item>
                      </template>
                    </template>
                  </draggable>
                </el-tab-pane>
              </el-tabs>
              <el-button title = "删除" style = "bottom: -20px;" @click.stop = "handleFormItemDelete(index)" class = "widget-action-delete" v-if = "selectFormItem.key == element.key" circle plain type = "danger">
                <i class = "iconfont icon-shanchu" ></i>
              </el-button>
            </div>
          </template>
          <template v-else>
            <form-item v-if = "element && element.key"  :key = "element.key" :element = "element" :select.sync = "selectFormItem" :index = "index" :data = "data"></form-item>
          </template>
        </template>
      </draggable>
    </el-form>
  </div>
</template>

<script>
import Draggable from 'vuedraggable'
import FormItem from './FormItem.vue'
export default {
  components: {
    Draggable,
    FormItem
  },
  props: ['data', 'select'],
  data () {
    return {
      selectFormItem: this.select
    }
  },
  mounted () {
    document.body.ondrop = function (event) {
      let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
      if (isFirefox) {
        event.preventDefault()
        event.stopPropagation()
      }
    }
  },
  methods: {
    // 选择单个元素时
    handleselectFormItem (index) {
      this.selectFormItem = this.data.list[index]
    },
    // 选择tabs标签页下的单个元素时
    handleselectTabsFormItem (elIndex, tabIndex, i) {
      this.selectFormItem = this.data.list[elIndex].tabList[tabIndex].list[i]
    },
    handleFormTabsItemDelete (elIndex, tabIndex, i) {
      if (this.data.list[elIndex].tabList[tabIndex].list.length - 1 === i) {
        if (i === 0) {
          this.selectFormItem = {}
        } else {
          this.selectFormItem = this.data.list[elIndex].tabList[tabIndex].list[i - 1]
        }
      } else {
        this.selectFormItem = this.data.list[elIndex].tabList[tabIndex].list[i + 1]
      }
      this.$nextTick(() => {
        this.data.list[elIndex].tabList[tabIndex].list.splice(i, 1)
      })
    },
    handleFormItemAdd (evt) {
      const newIndex = evt.newIndex
      // 为拖拽到容器的元素添加唯一 key
      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 999999)
      if (this.data.list[newIndex].category === 'dComponent') {
        let d = this.data.list[newIndex]
        Object.assign(d, {
          ...this.data.list[newIndex], // 原有的属性
          key,
          // 绑定键值
          model: this.data.list[newIndex].type + '_' + key,
          config: {
            ...this.data.list[newIndex].config,
            dataKey: this.data.list[newIndex].type + '_' + key,
            uid: key
          }
        })
        this.$set(this.data.list, newIndex, d)
      } else {
        this.$set(this.data.list, newIndex, {
          ...this.data.list[newIndex], // 原有的属性
          relatedComponents: [],
          options: {
            ...this.data.list[newIndex].options
          },
          key,
          // 绑定键值
          model: this.data.list[newIndex].type + '_' + key,
          rules: []
        })
        if (this.data.list[newIndex].type === 'radio' || this.data.list[newIndex].type === 'checkbox' || this.data.list[newIndex].type === 'select') {
          this.$set(this.data.list, newIndex, {
            ...this.data.list[newIndex],
            options: {
              ...this.data.list[newIndex].options,
              props: {
                value: '请输入',
                label: '请输入'
              },
              options: this.data.list[newIndex].options.options.map(item => ({
                ...item
              }))
            }
          })
        }
        if (this.data.list[newIndex].type === 'grid') {
          this.$set(this.data.list, newIndex, {
            ...this.data.list[newIndex],
            columns: this.data.list[newIndex].columns.map(item => ({...item}))
          })
        }
        if (this.data.list[newIndex].type === 'tabs') {
          this.$set(this.data.list, newIndex, {
            ...this.data.list[newIndex],
            tabList: this.data.list[newIndex].tabList.map(item => ({...item}))
          })
        }
        if (this.data.list[newIndex].type === 'table') {
          this.$set(this.data.list, newIndex, {
            ...this.data.list[newIndex],
            tableColumn: this.data.list[newIndex].tableColumn.map(item => ({...item})),
            totalData: [],
            tableData: [],
            filterData: [],
            options: {
              ...this.data.list[newIndex].options,
              rowEvents: []
            }
          })
        }
        if (this.data.list[newIndex].type === 'workflow') {
          this.$set(this.data.list, newIndex, {
            ...this.data.list[newIndex],
            options: {
              ...this.data.list[newIndex].options,
              workflowBtnEvents: []
            }
          })
        }
        if (Object.keys(this.data.list[newIndex].options).indexOf('events') >= 0) {
          this.$set(this.data.list, newIndex, {
            ...this.data.list[newIndex],
            options: {
              ...this.data.list[newIndex].options,
              events: []
            }
          })
        }
      }
      this.selectFormItem = this.data.list[newIndex]
    },
    // 表格中添加时
    handleFormItemColAdd ($event, row, colIndex) {
      const newIndex = $event.newIndex
      const oldIndex = $event.oldIndex
      const item = $event.item
      // 防止布局元素的嵌套拖拽
      if (item.className.indexOf('data-grid') >= 0 || item.className.indexOf('tabs-grid') >= 0) {
        // 如果是列表中拖拽的元素需要还原到原来位置
        item.tagName === 'DIV' && this.data.list.splice(oldIndex, 0, row.columns[colIndex].list[newIndex])
        row.columns[colIndex].list.splice(newIndex, 1)
        return false
      }
      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 999999)
      this.$set(row.columns[colIndex].list, newIndex, {
        ...row.columns[colIndex].list[newIndex],
        relatedComponents: [],
        options: {
          ...row.columns[colIndex].list[newIndex].options
        },
        key,
        // 绑定键值
        model: row.columns[colIndex].list[newIndex].type + '_' + key,
        rules: []
      })
      if (row.columns[colIndex].list[newIndex].type === 'radio' || row.columns[colIndex].list[newIndex].type === 'checkbox' || row.columns[colIndex].list[newIndex].type === 'select') {
        this.$set(row.columns[colIndex].list, newIndex, {
          ...row.columns[colIndex].list[newIndex],
          options: {
            ...row.columns[colIndex].list[newIndex].options,
            props: {
              value: '请输入',
              label: '请输入'
            },
            options: row.columns[colIndex].list[newIndex].options.options.map(item => ({
              ...item
            }))
          }
        })
      }
      if (row.columns[colIndex].list[newIndex].type === 'table') {
        this.$set(row.columns[colIndex].list, newIndex, {
          ...row.columns[colIndex].list[newIndex],
          tableColumn: row.columns[colIndex].list[newIndex].tableColumn.map(item => ({...item})),
          totalData: [],
          tableData: [],
          filterData: [],
          options: {
            ...row.columns[colIndex].list[newIndex].options,
            rowEvents: []
          }
        })
      }
      if (row.columns[colIndex].list[newIndex].type === 'workflow') {
        this.$set(row.columns[colIndex].list, newIndex, {
          ...row.columns[colIndex].list[newIndex],
          options: {
            ...row.columns[colIndex].list[newIndex].options,
            workflowBtnEvents: []
          }
        })
      }
      if (Object.keys(row.columns[colIndex].list[newIndex].options).indexOf('events') >= 0) {
        this.$set(row.columns[colIndex].list, newIndex, {
          ...row.columns[colIndex].list[newIndex],
          options: {
            ...row.columns[colIndex].list[newIndex].options,
            events: []
          }
        })
      }
      this.selectFormItem = row.columns[colIndex].list[newIndex]
    },
    // tab中添加内容
    handleFormItemTabAdd ($event, tab, tabIndex) {
      const newIndex = $event.newIndex
      const oldIndex = $event.oldIndex
      const item = $event.item
      // 防止布局元素的嵌套拖拽
      if (item.className.indexOf('tabs-grid') >= 0) {
        // 如果是列表中拖拽的元素需要还原到原来位置
        item.tagName === 'DIV' && this.data.list.splice(oldIndex, 0, tab.tabList[tabIndex].list[newIndex])
        tab.tabList[tabIndex].list.splice(newIndex, 1)
        return false
      }
      const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 999999)
      this.$set(tab.tabList[tabIndex].list, newIndex, {
        ...tab.tabList[tabIndex].list[newIndex],
        relatedComponents: [],
        options: {
          ...tab.tabList[tabIndex].list[newIndex].options
        },
        key,
        // 绑定键值
        model: tab.tabList[tabIndex].list[newIndex].type + '_' + key,
        rules: []
      })
      if (tab.tabList[tabIndex].list[newIndex].type === 'radio' || tab.tabList[tabIndex].list[newIndex].type === 'checkbox' || tab.tabList[tabIndex].list[newIndex].type === 'select') {
        this.$set(tab.tabList[tabIndex].list, newIndex, {
          ...tab.tabList[tabIndex].list[newIndex],
          options: {
            ...tab.tabList[tabIndex].list[newIndex].options,
            props: {
              value: '请输入',
              label: '请输入'
            },
            options: tab.tabList[tabIndex].list[newIndex].options.options.map(item => ({
              ...item
            }))
          }
        })
      }
      if (tab.tabList[tabIndex].list[newIndex].type === 'table') {
        this.$set(tab.tabList[tabIndex].list, newIndex, {
          ...tab.tabList[tabIndex].list[newIndex],
          tableColumn: tab.tabList[tabIndex].list[newIndex].tableColumn.map(item => ({...item})),
          totalData: [],
          tableData: [],
          filterData: [],
          options: {
            ...tab.tabList[tabIndex].list[newIndex].options,
            rowEvents: []
          }
        })
      }
      if (tab.tabList[tabIndex].list[newIndex].type === 'workflow') {
        this.$set(tab.tabList[tabIndex].list, newIndex, {
          ...tab.tabList[tabIndex].list[newIndex],
          options: {
            ...tab.tabList[tabIndex].list[newIndex].options,
            workflowBtnEvents: []
          }
        })
      }
      if (Object.keys(tab.tabList[tabIndex].list[newIndex].options).indexOf('events') >= 0) {
        this.$set(tab.tabList[tabIndex].list, newIndex, {
          ...tab.tabList[tabIndex].list[newIndex],
          options: {
            ...tab.tabList[tabIndex].list[newIndex].options,
            events: []
          }
        })
      }
      if (tab.tabList[tabIndex].list[newIndex].type === 'grid') {
        this.$set(tab.tabList[tabIndex].list, newIndex, {
          ...tab.tabList[tabIndex].list[newIndex],
          columns: tab.tabList[tabIndex].list[newIndex].columns.map(item => ({...item}))
        })
      }
      this.selectFormItem = tab.tabList[tabIndex].list[newIndex]
    },
    // 点击删除时
    handleFormItemDelete (index) {
      if (this.data.list.length - 1 === index) {
        if (index === 0) {
          this.selectFormItem = {}
        } else {
          this.selectFormItem = this.data.list[index - 1]
        }
      } else {
        this.selectFormItem = this.data.list[index + 1]
      }
      this.$nextTick(() => {
        this.data.list.splice(index, 1)
      })
    }
  },
  watch: {
    select (val) {
      this.selectFormItem = val
    },
    selectFormItem: {
      handler (val) {
        this.$emit('update:select', val)
      },
      deep: true
    }
  }
}
</script>
